package com.time.timespace.commons.utils;

import cn.idev.excel.FastExcel;
import com.time.timespace.domain.entity.Category;
import com.time.timespace.handler.ExcelCellStyleHandler;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class ExcelExportUtil {

    /**
     * 构建动态表头和数据
     *
     * @param dataMap key:月份, value:分类金额Map
     */
    public static void export(HttpServletResponse response, Map<String, Map<String, BigDecimal>> dataMap, List<Category> categoryList, String fileName) throws IOException {
        HashMap<String, String> categoryMap = categoryList.stream().collect(HashMap::new, (m, v) -> m.put(v.getValue(), v.getLabel()), HashMap::putAll);
        // 获取所有分类（动态列）
        List<Category> sortCategoryList = categoryList.stream().sorted(Comparator.comparing(Category::getId, Long::compareTo)).toList();
        // 1. 构建表头
        List<List<String>> head = new ArrayList<>();
        // 固定列
        head.add(Collections.singletonList("月份"));
        // 动态列
        sortCategoryList.forEach(category -> {
            head.add(Collections.singletonList(categoryMap.get(category.getValue())));
        });
        // 2. 构建数据行
        List<List<Object>> dataList = new ArrayList<>();
        dataMap.forEach((month, amountMap) -> {
            List<Object> row = new ArrayList<>();
            row.add(month); // 月份列
            sortCategoryList.forEach(category ->
                    row.add(amountMap.getOrDefault(category.getValue(), BigDecimal.ZERO))); // 动态列数据
            dataList.add(row);
        });
        // 根据月份排序
        dataList.sort((row1, row2) -> {
            // 提取月份字符串并转换为数字
            int month1 = extractMonthNumber((String) row1.get(0));
            int month2 = extractMonthNumber((String) row2.get(0));
            // 按数字升序排列
            return Integer.compare(month1, month2);
        });

        // 设置字符编码
        response.setCharacterEncoding("UTF-8");

        // 处理中文文件名
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8)
                .replaceAll("\\+", "%20");  // 处理空格问题

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition",
                "attachment; filename=\"" + encodedFileName + "\"; " +
                        "filename*=UTF-8''" + encodedFileName);

        // 3. 写入Excel
        FastExcel.write(response.getOutputStream())
                .registerWriteHandler(new ExcelCellStyleHandler())
                .head(head)
                .sheet("年度分类报表")
                .doWrite(dataList);
    }

    private static int extractMonthNumber(String monthStr) {
        // 移除非数字字符（如 "月"），剩余部分转为整数
        return Integer.parseInt(monthStr.replaceAll("\\D+", ""));
    }
}
